<template>
  <section
    class="oce-progress"
    id="oce-progress"
    @mouseover="hover = true"
    @mouseleave="hover = false"
    @click="setAxis"
    @mousemove="showTip"
  >
    <div
      class="progress"
      :style="{
        background: option.bgColor || '#EBEEF5',
        height: (option.width || 3) + 'px',
        'border-radius': (option.radius || 1) + 'px',
      }"
      ref="progress"
    >
      <!-- 主轴 -->
      <div
        class="axis"
        :style="{
          background: option.color || '#67C23A',
          height: (option.width || 3) + 'px',
          'border-radius': (option.radius || 1) + 'px',
          width: axisWidth,
        }"
      ></div>

      <!-- 副轴 -->
      <div
        class="assistant"
        :style="{
          background: option.assColor || '#777',
          height: (option.width || 3) + 'px',
          'border-radius': (option.radius || 1) + 'px',
          width: assWidth,
        }"
      ></div>

      <!-- 标记点 -->
      <div
        class="point"
        :style="{
          background: option.pointColor || '#67C23A',
          height: (option.endpointWidth || 8) + 'px',
          width: (option.endpointWidth || 8) + 'px',
          top:
            '-' +
            ((option.endpointWidth || 8) - (option.width || 3)) / 2 +
            'px',
          left: `calc(${axisWidth} - ${(option.endpointWidth || 8) / 2}px)`,
          transform: hover ? 'scale(1)' : 'scale(0)',
        }"
        ref="point"
        @click.stop
      ></div>

      <!-- 气泡提示 -->
      <div
        v-if="option.isTip"
        class="tip"
        v-show="tipLeft && hover"
        :style="{ left: tipLeft - 20 + 'px' }"
      >
        {{ tipText }}
      </div>
    </div>
  </section>
</template>

<script>
/**
 * 进度条组件
 */
export default {
  name: "OceProgress",
  data() {
    return {
      hover: false,
      axisValue: 50,
      assistantValue: 70,
      tipLeft: 0,
      offsetWidth: 0,
    };
  },
  props: {
    // 基础信息设置
    option: {
      type: Object,
      default: () => {
        return {
          // 最大值
          max: 100,
          // 是否开启副轴
          isAssistant: false,
          // 宽度(px)
          width: 3,
          // 端点宽度(px)
          endpointWidth: 9,
          // 背景色
          bgColor: "#EBEEF5",
          // 主轴颜色
          color: "#67C23A",
          // 副轴颜色
          assColor: "#777",
          // 端点颜色
          pointColor: "#67C23A",
          // 圆角
          radius: 1,
          // 数据拦截
          dataInterception: false,
          // 显示气泡
          isTip: true,
        };
      },
    },
    axisNum: {
      type: Number,
      default: 50,
    },
    assistantNum: {
      type: Number,
      default: 70,
    },
    // tip格式化
    formatter: {
      type: Function,
    },
  },
  watch: {
    axisNum(val) {
      this.axisValue = val;
    },
    assistantNum(val) {
      this.assistantValue = val;
    },
    axisValue(val) {
      this.$emit("update:axisNum", val);
    },
    assistantValue(val) {
      this.$emit("update:assistantNum", val);
    },
  },
  created() {
    this.$nextTick(() => {
      this.mousedownhandler();
      this.offsetWidth = this.$el.offsetWidth;
      this.axisValue = this.axisNum;
      this.assistantValue = this.assistantNum;
    });
  },
  computed: {
    tipText: function () {
      if (!this.offsetWidth) return "";
      if (this.formatter)
        return this.formatter(
          (this.tipLeft / this.$el.offsetWidth) * (this.option.max || 100)
        );
      return Math.ceil(
        (this.tipLeft / this.$el.offsetWidth) * (this.option.max || 100)
      );
    },
    axisWidth: function () {
      // console.log(this.axisValue)
      return ((this.axisValue ?? 50) / (this.option.max || 100)) * 100 + "%";
    },
    assWidth: function () {
      return (
        ((this.assistantValue ?? 50) / (this.option.max || 100)) * 100 + "%"
      );
    },
  },
  methods: {
    // 点击
    setAxis(e) {
      let axisValue =
        (e.offsetX / this.$el.offsetWidth) * (this.option.max || 100);
      if (this.option.dataInterception) {
        this.$emit("intercept", axisValue);
      } else {
        this.axisValue = axisValue;
      }
    },
    // 拖动
    mousedownhandler(e) {
      // console.log(e)
      let point = this.$refs.point;
      point.onmousedown = (de) => {
        let downX = de.clientX;
        let downWidth =
          (this.$el.offsetWidth * this.axisValue) / (this.option.max || 100);
        document.body.style.cursor = "pointer";

        document.oncontextmenu = function () {
          return false;
        };
        document.onselectstart = function () {
          return false;
        };
        document.onmousemove = (e) => {
          document.body.style.cursor = "pointer";
          let axisValue =
            ((e.clientX - downX + downWidth) / this.$el.offsetWidth) *
            (this.option.max || 100);
          //console.log(axisValue);
          if (axisValue < 0) axisValue = "0";
          if (axisValue > (this.option.max || 100))
            axisValue = this.option.max || 100;
          if (this.option.dataInterception) {
            this.$emit("intercept", axisValue);
          } else {
            this.axisValue = axisValue;
          }
        };
        document.onmouseup = () => {
          document.onmousemove = document.onmouseup = null;
          document.body.style.cursor = "";
          document.oncontextmenu = function () {
            return true;
          };
          document.onselectstart = function () {
            return true;
          };
        };
      };
    },
    // 气泡控制
    showTip(e) {
      // console.log(e, e.offsetX,e.clientX,e.scrollX,e.layerX)
      let el = this.$el.getClientRects()[0];
      // console.log(el.left , el.x)
      if (e.offsetX) this.tipLeft = e.clientX - el.left;
    },
  },
};
</script>

<style lang="scss" scoped>
.oce-progress {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;

  .progress {
    width: 100%;
    position: relative;

    .axis,
    .assistant {
      position: absolute;
      top: 0;
      left: 0;
      cursor: pointer;
      // transition: all 0.3s;
    }
    .axis {
      z-index: 10;
    }

    .assistant {
      z-index: 5;
    }

    .point {
      position: absolute;
      border-radius: 50%;
      transition: transform 0.3s;
      z-index: 15;

      &:hover {
        cursor: pointer;
      }
    }

    .tip {
      position: absolute;
      width: 40px;
      height: 18px;
      border-radius: 3px;
      background-color: rgba(0, 0, 0, 0.5);
      // background-color: red;
      text-align: center;
      top: -25px;
    }
  }
}
</style>
